/**
 * 重构的Webhook传输模块
 * 集中管理配送单webhook通知功能
 * 优化容器码记录和传输流程
 * 支持从 mdye.env.config 读取运行时参数，实现参数化配置
 */

import { 
  API_CONFIG, 
  WORKSHEET_IDS, 
  DELIVERY_ORDER_FIELDS,
  CONTAINER_FIELDS,
  WEBHOOKS,
  getFieldValue
} from '../config/delivery-config.js'

// 配置常量 - 支持从 mdye.env.config 读取
const WEBHOOK_CONFIG = {
  // 主要webhook URL - 从配置读取
  get DELIVERY_WEBHOOK_URL() {
    return WEBHOOKS.DELIVERY_WEBHOOK_URL;
  },
  
  // 备用webhook URL (可选)
  get BACKUP_WEBHOOK_URL() {
    return readEnv(['backupWebhookUrl', 'BACKUP_WEBHOOK_URL'], null);
  },
  
  // 重试配置
  RETRY_ATTEMPTS: 3,
  RETRY_DELAY: 1000, // 毫秒
  
  // 超时配置
  TIMEOUT: 30000, // 30秒
  
  // 数据存储配置
  STORAGE_PREFIX: 'webhook_delivery_',
  CONTAINER_STORAGE_PREFIX: 'order_containers_'
}

/**
 * Webhook服务类
 */
class WebhookService {
  constructor() {
    // 内存中的订单容器码映射存储
    this.orderContainerMap = new Map()
    
    // 待发送的webhook队列
    this.pendingWebhooks = []
    
    // 发送状态记录
    this.sendingStatus = new Map()
    
    this.initializeService()
  }
  
  /**
   * 初始化服务
   */
  initializeService() {
    
    // 从sessionStorage恢复数据
    this.restoreFromStorage()
    
    // 设置定期清理任务
    this.setupCleanupTask()
    
  }
  
  /**
   * 记录配送单创建时的容器码
   * @param {string} orderId - 订单ID
   * @param {Array} containers - 容器数组
   * @param {Object} orderData - 订单数据
   */
  recordOrderContainers(orderId, containers, orderData = {}) {
    
    if (!orderId || !Array.isArray(containers)) {
      console.warn('无效的订单ID或容器数据')
      return false
    }
    
    // 提取容器码信息
    const containerInfo = containers.map(container => {
      const containerCode = this.extractContainerCode(container)
      return {
        id: container.id || container.rowid,
        code: containerCode,
        rawData: container.rawData || container,
        recordTime: new Date().toISOString()
      }
    })
    
    // 构建完整的订单数据记录
    const orderRecord = {
      orderId: orderId,
      containers: containers,
      containerCodes: containerInfo,
      orderData: orderData,
      recordTime: new Date().toISOString(),
      webhookSent: false
    }
    
    // 存储到内存映射
    this.orderContainerMap.set(orderId, orderRecord)
    
    // 备份到sessionStorage
    const storageKey = WEBHOOK_CONFIG.CONTAINER_STORAGE_PREFIX + orderId
    try {
      sessionStorage.setItem(storageKey, JSON.stringify(orderRecord))
    } catch (error) {
      console.warn('备份到sessionStorage失败:', error)
    }
    
    return true
  }
  
  /**
   * 发运确认时发送webhook
   * @param {string} orderId - 订单ID  
   * @param {Object} shipmentData - 发运数据
   */
  async sendShipmentWebhook(orderId, shipmentData = {}) {
    
    // 检查是否正在发送中
    if (this.sendingStatus.get(orderId)) {
      return { success: false, message: '正在发送中' }
    }
    
    // 设置发送状态
    this.sendingStatus.set(orderId, {
      status: 'sending',
      startTime: Date.now()
    })
    
    try {
      // 尝试从后端API获取容器码信息
      const orderContainers = await this.getOrderContainersFromAPI(orderId)
      
      let orderRecord = null
      
      if (orderContainers && orderContainers.length > 0) {
        // 如果从API获取到容器码，构建临时订单记录
        orderRecord = {
          orderId: orderId,
          containers: orderContainers,
          containerCodes: orderContainers.map((code, index) => ({
            id: `api_container_${index}`,
            code: code,
            recordTime: new Date().toISOString()
          })),
          orderData: shipmentData,
          recordTime: new Date().toISOString(),
          webhookSent: false,
          dataSource: 'api'
        }
      } else {
        // 回退到原有的记录获取方式
        orderRecord = this.getOrderRecord(orderId)
        
        if (!orderRecord) {
          throw new Error(`未找到订单 ${orderId} 的容器码记录`)
        }
      }
      
      // 构建webhook数据
      const webhookData = this.buildWebhookData(orderRecord, shipmentData)
      
      
      // 发送webhook
      const result = await this.sendWebhookWithRetry(webhookData)
      
      if (result.success) {
        // 标记为已发送
        orderRecord.webhookSent = true
        orderRecord.sentTime = new Date().toISOString()
        
        // 只有来自前端记录的数据才需要存储和清理
        if (orderRecord.dataSource !== 'api') {
          this.orderContainerMap.set(orderId, orderRecord)
          
          // 可选：发送成功后清理存储
          setTimeout(() => {
            this.cleanupOrderRecord(orderId)
          }, 5000) // 5秒后清理
        }
        
      }
      
      return result
      
    } catch (error) {
      console.error('❌ 发运webhook发送失败:', error)
      return {
        success: false,
        message: error.message,
        error: error
      }
    } finally {
      // 清除发送状态
      this.sendingStatus.delete(orderId)
    }
  }
  
  /**
   * 从API获取订单的容器码信息
   * @param {string} orderId - 订单ID
   * @returns {Promise<Array>} 容器码数组
   */
  async getOrderContainersFromAPI(orderId) {
    
    try {
      // API配置 - 使用动态配置
      const apiConfig = {
        baseURL: API_CONFIG.baseURL,
        appKey: API_CONFIG.appKey,
        sign: API_CONFIG.sign,
        worksheetId: WORKSHEET_IDS.DELIVERY_ORDERS, // 配送单工作表ID
        containerCodesFieldId: DELIVERY_ORDER_FIELDS.CONTAINER_CODES // 拥有容器字段ID
      }
      
      // 构建API请求
      const requestData = {
        appKey: apiConfig.appKey,
        sign: apiConfig.sign,
        worksheetId: apiConfig.worksheetId,
        pageSize: 1,
        pageIndex: 1,
        filters: [
          {
            controlId: 'rowid', // 使用rowid字段搜索
            dataType: 2,
            spliceType: 1,
            filterType: 1,
            values: [orderId]
          }
        ]
      }
      
      
      // 发送API请求
      const response = await fetch(`${apiConfig.baseURL}/getFilterRows`, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json'
        },
        body: JSON.stringify(requestData)
      })
      
      if (!response.ok) {
        throw new Error(`API请求失败: ${response.status} ${response.statusText}`)
      }
      
      const result = await response.json()
      
      // 处理API响应
      let rows = null
      if (result.rows) {
        rows = result.rows
      } else if (result.data && result.data.rows) {
        rows = result.data.rows
      } else if (result.data && Array.isArray(result.data)) {
        rows = result.data
      }
      
      if (rows && Array.isArray(rows) && rows.length > 0) {
        const orderRecord = rows[0]
        
        // 获取容器码字段的值
        const containerCodesValue = orderRecord[apiConfig.containerCodesFieldId]
        
        if (containerCodesValue && typeof containerCodesValue === 'string') {
          // 按逗号分割容器码
          const containerCodes = containerCodesValue.split(',')
            .map(code => code.trim())
            .filter(code => code.length > 0)
          
          return containerCodes
        } else {
          console.warn('⚠️ 配送单中未找到容器码信息')
          return []
        }
      } else {
        console.warn('⚠️ 未找到对应的配送单记录')
        return []
      }
      
    } catch (error) {
      console.error('❌ 从API获取容器码失败:', error)
      return []
    }
  }

  /**
   * 获取订单记录
   * @param {string} orderId - 订单ID
   * @returns {Object|null} 订单记录
   */
  getOrderRecord(orderId) {
    // 首先从内存中获取
    let orderRecord = this.orderContainerMap.get(orderId)
    
    if (orderRecord) {
      return orderRecord
    }
    
    // 尝试从sessionStorage恢复
    const storageKey = WEBHOOK_CONFIG.CONTAINER_STORAGE_PREFIX + orderId
    try {
      const storedData = sessionStorage.getItem(storageKey)
      if (storedData) {
        orderRecord = JSON.parse(storedData)
        // 恢复到内存中
        this.orderContainerMap.set(orderId, orderRecord)
        return orderRecord
      }
    } catch (error) {
      console.warn('从sessionStorage恢复数据失败:', error)
    }
    
    console.warn('未找到订单记录:', orderId)
    return null
  }
  
  /**
   * 构建webhook数据
   * @param {Object} orderRecord - 订单记录
   * @param {Object} shipmentData - 发运数据
   * @returns {Object} webhook数据
   */
  buildWebhookData(orderRecord, shipmentData) {
    const containerCodes = orderRecord.containerCodes.map(c => c.code).filter(code => code)
    const containerIds = orderRecord.containerCodes.map(c => c.id).filter(id => id)
    
    return {
      // 基础信息
      formId: containerIds.length > 0 ? containerIds[0] : orderRecord.orderId,
      orderId: orderRecord.orderId,
      clickTime: new Date().toISOString(),
      
      // 容器信息 - 核心数据
      containerCodes: containerCodes.join(','), // 容器码字符串（逗号分隔）
      containerIds: containerIds.join(','),     // 容器ID字符串（逗号分隔）
      containerCount: containerCodes.length,    // 容器数量
      
      // 订单信息
      deliveryMethod: orderRecord.orderData.method || shipmentData.deliveryMethod || '',
      destination: orderRecord.orderData.destination || shipmentData.destination || '',
      driver: orderRecord.orderData.driver || shipmentData.driver || '',
      vehicle: orderRecord.orderData.vehicle || shipmentData.vehicle || '',
      
      // 发运信息
      shipmentStatus: shipmentData.status || 'confirmed',
      shipmentTime: shipmentData.shipmentTime || new Date().toISOString(),
      
      // 元数据
      dataSource: 'webhook-service',
      version: '2.0',
      recordTime: orderRecord.recordTime,
      
      // 调试信息
      debug: {
        totalContainersRecorded: orderRecord.containers.length,
        containerCodesExtracted: containerCodes.length,
        hasValidCodes: containerCodes.length > 0
      }
    }
  }
  
  /**
   * 带重试机制的webhook发送
   * @param {Object} data - webhook数据
   * @returns {Promise<Object>} 发送结果
   */
  async sendWebhookWithRetry(data) {
    const maxAttempts = WEBHOOK_CONFIG.RETRY_ATTEMPTS
    let lastError = null
    
    for (let attempt = 1; attempt <= maxAttempts; attempt++) {
      
      try {
        const result = await this.sendWebhookRequest(data)
        
        if (result.success) {
          return result
        } else {
          lastError = new Error(result.message)
        }
        
      } catch (error) {
        lastError = error
      }
      
      // 如果不是最后一次尝试，等待后重试
      if (attempt < maxAttempts) {
        const delay = WEBHOOK_CONFIG.RETRY_DELAY * attempt // 递增延迟
        await this.sleep(delay)
      }
    }
    
    return {
      success: false,
      message: `经过${maxAttempts}次尝试后仍然失败`,
      lastError: lastError?.message || '未知错误'
    }
  }
  
  /**
   * 发送单次webhook请求
   * @param {Object} data - webhook数据
   * @returns {Promise<Object>} 发送结果
   */
  async sendWebhookRequest(data) {
    
    const controller = new AbortController()
    const timeoutId = setTimeout(() => controller.abort(), WEBHOOK_CONFIG.TIMEOUT)
    
    try {
      const response = await fetch(WEBHOOK_CONFIG.DELIVERY_WEBHOOK_URL, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          'User-Agent': 'Delivery-Webhook-Service/2.0'
        },
        body: JSON.stringify(data),
        signal: controller.signal
      })
      
      clearTimeout(timeoutId)
      
      const responseText = await response.text()
      
      
      if (response.ok) {
        return {
          success: true,
          status: response.status,
          response: responseText
        }
      } else {
        return {
          success: false,
          status: response.status,
          message: `HTTP ${response.status}: ${response.statusText}`,
          response: responseText
        }
      }
      
    } catch (error) {
      clearTimeout(timeoutId)
      
      if (error.name === 'AbortError') {
        return {
          success: false,
          message: '请求超时',
          timeout: true
        }
      }
      
      return {
        success: false,
        message: error.message,
        error: error
      }
    }
  }
  
  /**
   * 提取容器码
   * @param {Object} container - 容器对象
   * @returns {string} 容器码
   */
  extractContainerCode(container) {
    if (!container) {
      return `UNKNOWN_${Date.now()}`
    }
    
    // 多种方式尝试提取容器码
    const possibleSources = [
      // 方法1: 从rawData中的指定字段获取
      () => container.rawData?.[CONTAINER_FIELDS.CONTAINER_CODE],
      
      // 方法2: 从rawData的containerCode属性获取
      () => container.rawData?.containerCode,
      
      // 方法3: 从rawData的code属性获取
      () => container.rawData?.code,
      
      // 方法4: 从容器对象的指定字段获取
      () => container[CONTAINER_FIELDS.CONTAINER_CODE],
      
      // 方法5: 从容器对象的containerCode属性获取
      () => container.containerCode,
      
      // 方法6: 从容器对象的code属性获取
      () => container.code,
      
      // 方法7: 使用容器ID作为备用
      () => container.id || container.rowid
    ]
    
    for (const source of possibleSources) {
      try {
        const code = source()
        if (code && String(code).trim()) {
          return String(code).trim()
        }
      } catch (error) {
        // 忽略单个提取方法的错误，继续尝试下一个
        continue
      }
    }
    
    // 如果所有方法都失败，生成一个唯一标识符
    return `CONTAINER_${Date.now()}_${Math.random().toString(36).substring(2, 8)}`
  }
  
  /**
   * 从sessionStorage恢复数据
   */
  restoreFromStorage() {
    
    try {
      const keys = Object.keys(sessionStorage)
      const containerKeys = keys.filter(key => key.startsWith(WEBHOOK_CONFIG.CONTAINER_STORAGE_PREFIX))
      
      
      containerKeys.forEach(key => {
        try {
          const data = JSON.parse(sessionStorage.getItem(key))
          if (data && data.orderId) {
            this.orderContainerMap.set(data.orderId, data)
          }
        } catch (error) {
          console.warn(`恢复记录失败 ${key}:`, error)
          // 删除损坏的记录
          sessionStorage.removeItem(key)
        }
      })
      
      
    } catch (error) {
      console.error('恢复数据时出错:', error)
    }
  }
  
  /**
   * 清理订单记录
   * @param {string} orderId - 订单ID
   */
  cleanupOrderRecord(orderId) {
    
    // 从内存中删除
    this.orderContainerMap.delete(orderId)
    
    // 从sessionStorage中删除
    const storageKey = WEBHOOK_CONFIG.CONTAINER_STORAGE_PREFIX + orderId
    sessionStorage.removeItem(storageKey)
    
  }
  
  /**
   * 设置定期清理任务
   */
  setupCleanupTask() {
    // 每30分钟清理一次过期数据
    setInterval(() => {
      this.cleanupExpiredRecords()
    }, 30 * 60 * 1000)
  }
  
  /**
   * 清理过期记录
   */
  cleanupExpiredRecords() {
    
    const now = Date.now()
    const expireTime = 24 * 60 * 60 * 1000 // 24小时
    const expiredOrders = []
    
    this.orderContainerMap.forEach((record, orderId) => {
      const recordTime = new Date(record.recordTime).getTime()
      if (now - recordTime > expireTime) {
        expiredOrders.push(orderId)
      }
    })
    
    expiredOrders.forEach(orderId => {
      this.cleanupOrderRecord(orderId)
    })
    
  }
  
  /**
   * 获取服务状态
   * @returns {Object} 状态信息
   */
  getServiceStatus() {
    return {
      activeOrders: this.orderContainerMap.size,
      pendingWebhooks: this.pendingWebhooks.length,
      sendingCount: this.sendingStatus.size,
      config: {
        webhookUrl: WEBHOOK_CONFIG.DELIVERY_WEBHOOK_URL,
        retryAttempts: WEBHOOK_CONFIG.RETRY_ATTEMPTS,
        timeout: WEBHOOK_CONFIG.TIMEOUT
      },
      uptime: Date.now() - this.startTime
    }
  }
  
  /**
   * 工具方法：休眠
   * @param {number} ms - 毫秒数
   * @returns {Promise}
   */
  sleep(ms) {
    return new Promise(resolve => setTimeout(resolve, ms))
  }
}

// 创建单例实例
let webhookServiceInstance = null

export function getWebhookService() {
  if (!webhookServiceInstance) {
    webhookServiceInstance = new WebhookService()
  }
  return webhookServiceInstance
}

// 导出服务实例和配置
export { WebhookService, WEBHOOK_CONFIG }
export default getWebhookService()